home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
program
/
szadb1_4.zoo
/
src
/
dis3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-13
|
16KB
|
817 lines
/* Copyright (c) 1990 by Sozobon, Limited. Authors: Johann Ruegg, Don Dugger
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*
* dis3.c
*/
/*
* Modifications:
* - in case of ailure to disassemble print operand as a constant
* in 'dc.w' instruction
* - make printout to align in a nicer way
*
* Michal Jaegermann, November 1990
*/
#include "adb.h"
extern long dot;
extern int dotoff;
extern int opcode_pos; /* this value depends on resolution */
#define DOT (dot+dotoff)
int cursz;
nextw ()
{
return getwd ();
}
long
nextl ()
{
unsigned int i[2];
i[0] = getwd ();
i[1] = getwd ();
return ((long) i[0]) << 16 | i[1];
}
int op0 (), op1 (), op2 (), op3 (), op4 (), op5 (), op6 (), op7 ();
int op8 (), op9 (), opa (), opb (), opc (), opd (), ope (), opf ();
int (*funhi[]) () = { op0, op1, op2, op3, op4, op5, op6, op7,
op8, op9, opa, opb, opc, opd, ope, opf
};
puti ()
{
unsigned int op;
int ar_pos;
align (opcode_pos);
op = nextw ();
if (!(*funhi[op >> 12]) (op, ar_pos = opcode_pos + ALIGN_OP)) {
prt ("dc.w");
align (ar_pos);
prtn ((unsigned long) op, 0);
}
}
#define M_IMM 1
#define M_PX 2
#define M_POFF 4
#define M_ABSL 010
#define M_ABSW 020
#define M_AX 040
#define M_AOFF 0100
#define M_ADEC 0200
#define M_AINC 0400
#define M_ATA 01000
#define M_AREG 02000
#define M_DREG 04000
valid (mode, reg, mask)
{
if (mode == 7)
switch (reg) {
case 0:
return mask & M_ABSW;
case 1:
return mask & M_ABSL;
case 2:
return mask & M_POFF;
case 3:
return mask & M_PX;
case 4:
return mask & M_IMM;
default:
return 0;
}
else
switch (mode) {
case 0:
return mask & M_DREG;
case 1:
return mask & M_AREG;
case 2:
return mask & M_ATA;
case 3:
return mask & M_AINC;
case 4:
return mask & M_ADEC;
case 5:
return mask & M_AOFF;
case 6:
return mask & M_AX;
}
}
ix_str (n)
{
int op, r;
char c;
char *fmt;
op = nextw ();
r = (op >> 12) & 7;
c = (op & 0x800) ? 'l' : 'w';
if (n >= 8) {
if (op < 0)
fmt = "%i(pc,%a.%c)";
else
fmt = "%i(pc,%d.%c)";
prtf (fmt, (char) op, r, c);
}
else {
if (op < 0)
fmt = "%i(%a,%a.%c)";
else
fmt = "%i(%a,%d.%c)";
prtf (fmt, (char) op, n, r, c);
}
}
modepr (mode, reg)
{
char *p;
switch (mode) {
case 0:
prtf ("%d", reg);
break;
case 1:
prtf ("%a", reg);
break;
case 2:
prtf ("(%a)", reg);
break;
case 3:
prtf ("(%a)+", reg);
break;
case 4:
prtf ("-(%a)", reg);
break;
case 5:
prtf ("%i(%a)", nextw (), reg);
break;
case 6:
ix_str (reg);
break;
case 7:
switch (reg) {
case 0:
prtf ("%i", nextw ());
break;
case 1:
longval ();
break;
case 2:
prtf ("%i(pc)", nextw ());
break;
case 3:
ix_str (8);
break;
case 4:
switch (cursz) {
case 0:
case 1:
prtf ("#%i", nextw ());
break;
case 2:
putchr ('#');
longval ();
break;
}
break;
}
}
}
longval ()
{
long l;
struct sym *sp;
prtf ("%A", nextl ());
}
char szchr[] = {'b', 'w', 'l'};
struct optbl {
char sel[6];
char *name;
int allow;
char arg[4];
char sz;
};
struct optbl t0[] = {
{"0s", "or", 05770, "ie"},
{"00", "or", 1, "ic"},
{"01", "or", 1, "is", 1},
{"*4", "btst", 05777, "De"},
{"*5", "bchg", 05770, "De"},
{"*6", "bclr", 05770, "De"},
{"*7", "bset", 05770, "De"},
{"*4", "movep.w", 02000, "oD"},
{"*5", "movep.l", 02000, "oD"},
{"*6", "movep.w", 02000, "Do"},
{"*7", "movep.l", 02000, "Do"},
{"1s", "and", 05770, "ie"},
{"10", "and", 1, "ic"},
{"11", "and", 1, "is", 1},
{"2s", "sub", 05770, "ie"},
{"3s", "add", 05770, "ie"},
{"40", "btst", 05776, "ie"},
{"41", "bchg", 05770, "ie"},
{"42", "bclr", 05770, "ie"},
{"43", "bset", 05770, "ie"},
{"5s", "eor", 05770, "ie"},
{"50", "eor", 1, "ic"},
{"51", "eor", 1, "is", 1},
{"6s", "cmp", 05770, "ie"},
{0, 0, 0, 0}
};
op0 (op, pos)
unsigned int op;
int pos;
{
return tblop (op, t0, pos);
}
match (c, val)
{
switch (c) {
case '*':
return 1;
case 's':
return val <= 2;
case 'S':
return val >= 4 && val <= 6;
case 'z':
return val >= 1 && val <= 2;
case 'Z':
return val == 3 || val == 7;
default:
return val == (c - '0');
}
}
op1 (op, pos)
unsigned int op;
int pos;
{
int sm, sr, dm, dr;
sm = (op >> 3) & 7;
sr = op & 7;
dm = (op >> 6) & 7;
dr = (op >> 9) & 7;
cursz = 0;
if (valid (sm, sr, 07777) && valid (dm, dr, 05770)) {
prt ("move.b");
align (pos);
modepr (sm, sr);
putchr (',');
modepr (dm, dr);
return 1;
}
return 0;
}
op2 (op, pos)
unsigned int op;
int pos;
{
int sm, sr, dm, dr;
sm = (op >> 3) & 7;
sr = op & 7;
dm = (op >> 6) & 7;
dr = (op >> 9) & 7;
cursz = 2;
if (valid (sm, sr, 07777) && valid (dm, dr, 07770)) {
prt ("move.l");
align (pos);
modepr (sm, sr);
putchr (',');
modepr (dm, dr);
return 1;
}
return 0;
}
op3 (op, pos)
unsigned int op;
int pos;
{
int sm, sr, dm, dr;
sm = (op >> 3) & 7;
sr = op & 7;
dm = (op >> 6) & 7;
dr = (op >> 9) & 7;
cursz = 1;
if (valid (sm, sr, 07777) && valid (dm, dr, 07770)) {
prt ("move.w");
align (pos);
modepr (sm, sr);
putchr (',');
modepr (dm, dr);
return 1;
}
return 0;
}
struct optbl t4[] = {
{"0s", "negx", 05770, "e"},
{"03", "move.w", 05770, "se"},
{"*6", "chk", 05777, "eD"},
{"*7", "lea", 01176, "eA"},
{"1s", "clr", 05770, "e"},
{"2s", "neg", 05770, "e"},
{"23", "move.b", 05777, "ec"},
{"3s", "not", 05770, "e"},
{"33", "move.w", 05777, "es", 1},
{"40", "nbcd", 05770, "e"},
{"41", "swap", 04000, "d"},
{"41", "pea", 01176, "e"},
{"42", "ext.w", 04000, "d"},
{"42", "movem.w", 01170, "le"},
{"42", "movem.w", 00200, "Le"},
{"43", "movem.l", 01170, "le"},
{"43", "movem.l", 00200, "Le"},
{"43", "ext.l", 04000, "d"},
{"5s", "tst", 05770, "e"},
{"53", "tas", 05770, "e"},
{"53", "illegal", 0001, ""},
{"71", "trap", 06000, "t"},
{"71", "link", 01000, "ai", 1},
{"71", "unlk", 00400, "a"},
{"71", "move", 00200, "au"},
{"71", "move", 00100, "ua"},
{"7160", "reset", 0, ""},
{"7161", "nop", 0, ""},
{"7162", "stop", 0, ""},
{"7163", "rte", 0, ""},
{"7165", "rts", 0, ""},
{"7166", "trapv", 0, ""},
{"7167", "rtr", 0, ""},
{"72", "jsr", 01176, "e"},
{"73", "jmp", 01176, "e"},
{0, 0, 0, 0}
};
op4 (op, pos)
unsigned int op;
int pos;
{
int mode, reg, list;
if ((op & 07600) == 06200) {
reg = op & 7;
mode = (op >> 3) & 7;
if (valid (mode, reg, 01576)) {
prtf ("movem.%c", op & 0100 ? 'l' : 'w');
align (pos);
list = nextw ();
modepr (mode, reg);
putchr (',');
rlist (list);
return 1;
}
else
return 0;
}
return tblop (op, t4, pos);
}
tblop (op, tp, pos)
unsigned op;
register struct optbl